using System.Linq;
using Data;
using MoonFramework.Scripts.Event;
using MoonFramework.Scripts.Mono;
using MoonFramework.Scripts.Tool;
using MoonFramework.Template;
using Tool;
using Tool.Name;
using UnityEngine;

namespace GameTime
{
    /// <summary>
    ///     时间管理器
    /// </summary>
    public class TimeManager : BaseGameMono<TimeManager>
    {
        #region 运行中数据
        [SerializeField] private Light mainLight;
        public float timeScale = 1;
        private TimeFsm timeMachine;
        public int CurDay => _timeData.curDay;
        #endregion
        
        #region 存档数据
        private TimeData _timeData;
        #endregion

        public void Init()
        {
            _timeData = ArchiveManager.Instance.TimeData;
            timeMachine = new TimeFsm(_timeData.curState, this);
            EventCenter.Instance.SendCommand(EventName.SaveGame, OnGameClose);
            EventCenter.Instance.Callback("UpdateTimeState", timeMachine.curState is "MorningTime" or "NoonTime");
            EventCenter.Instance.Callback("UpdateDay", _timeData.curDay);
            UpdateTime();
        }

        private void UpdateTime()
        {
            var curState = (BaseTimeState)timeMachine.fsmStates[timeMachine.curState];
            if (timeMachine.curState != _timeData.curState) _timeData.curTime = float.MaxValue;
            _timeData.curTime = Mathf.Min(_timeData.curTime, curState.TimeStateData.durationTime);
            var nextState = timeMachine.transitionMap[timeMachine.curState].First();
            MonoManager.Instance.SendUpdateEvent(() =>
            {
                _timeData.curTime -= Time.deltaTime * timeScale;
                if (!curState.CheckAndCalTime(_timeData.curTime, nextState,
                        out var quaternion, out var color, out var sunIntensity))
                {
                    _timeData.curState = nextState;
                    timeMachine.ChangeState(nextState);
                    curState = (BaseTimeState)timeMachine.fsmStates[timeMachine.curState];
                    nextState =  timeMachine.transitionMap[timeMachine.curState].First();
                    _timeData.curTime = curState.TimeStateData.durationTime;
                }
                
                SetLight(sunIntensity, quaternion, color);
            });
        }

        private void SetLight(float intensity, Quaternion quaternion, Color color)
        {
            //设置环境光
            mainLight.transform.rotation = quaternion;
            mainLight.color = color;
            mainLight.intensity = intensity;
            RenderSettings.ambientIntensity = intensity;
        }

        private void OnGameClose()
        {
            MonoManager.Instance.RemoveUpdateEvent(UpdateTime);
            Destroy(mainLight);
            ArchiveManager.Instance.SaveTimeData(0);
        }
    }
}